function ModEditor.Internal.Sign(number)
	if number > 0 then
		return 1
	elseif number < 0 then
		return -1
	else
		return 0
	end
end
function ModEditor.Input.Process()
	local kx
	local ky
	if ModEditor.Input.RightShift or ModEditor.Input.LeftShift then
		kx = 0.01
		ky = 0.01
	else
		kx = 0.001
		ky = 0.001
	end
	local id1 = 0
	local id2 = 0
	if ModEditor.Camera.Current == 1 then
		id1 = 1
		id2 = -2
	elseif ModEditor.Camera.Current == 2 then
		id1 = -2
		id2 = 3
	elseif ModEditor.Camera.Current == 3 then
		id1 = 1
		id2 = 3
	end
	local state = get_shift_key_state()
	if state == 1 then
		ModEditor.Input.LeftShift = true
	elseif state == 2 then
		ModEditor.Input.RightShift = true
	elseif state ~= 0 then
		ModEditor.Input.LeftShift = true
		ModEditor.Input.RightShift = true
	end
	if (ModEditor.Input.RightShift or ModEditor.Input.LeftShift) and (ModEditor.Input.RightCtrl or ModEditor.Input.LeftCtrl) then
		id1 = 0
		id2 = 0
		if ModEditor.Camera.Current == 1 then
			if ModEditor.Input.MouseX < 100 then
				ModEditor.Camera.Angle = ModEditor.Camera.Angle + 2
			elseif ModEditor.Input.MouseX > get_option("width")-100 then
				ModEditor.Camera.Angle = ModEditor.Camera.Angle - 2
			end
		end
	end
	if ModEditor.Camera.Current == 1 then
		kx = kx*math.cos(math.pi/180*ModEditor.Camera.Angle)
		ky = ky*math.sin(math.pi/180*ModEditor.Camera.Angle)
	end
	if ((id1 ~= 0) and (id2 ~= 0)) and ((ModEditor.Input.LeftCtrl or ModEditor.Input.RightCtrl) or (ModEditor.Input.LeftShift or ModEditor.Input.RightShift)) then
		if ModEditor.Input.MouseX < 100 then
			ModEditor.Camera.Position[math.abs(id1)] = ModEditor.Camera.Position[math.abs(id1)] + ModEditor.Internal.Sign(id1)*kx*(100-ModEditor.Input.MouseX)
			if ModEditor.Camera.Current == 1 then
				ModEditor.Camera.Position[math.abs(id2)] = ModEditor.Camera.Position[math.abs(id2)] + ModEditor.Internal.Sign(id2)*ky*(100-ModEditor.Input.MouseX)
			end
		elseif ModEditor.Input.MouseX > get_option("width")-100 then
			ModEditor.Camera.Position[math.abs(id1)] = ModEditor.Camera.Position[math.abs(id1)] - ModEditor.Internal.Sign(id1)*kx*(100-(get_option("width")+1-ModEditor.Input.MouseX))
			if ModEditor.Camera.Current == 1 then
				ModEditor.Camera.Position[math.abs(id2)] = ModEditor.Camera.Position[math.abs(id2)] - ModEditor.Internal.Sign(id2)*ky*(100-(get_option("width")+1-ModEditor.Input.MouseX))
			end
		end
		if ModEditor.Input.MouseY < 100 then
			ModEditor.Camera.Position[math.abs(id2)] = ModEditor.Camera.Position[math.abs(id2)] + ModEditor.Internal.Sign(id2)*kx*(100-ModEditor.Input.MouseY)
			if ModEditor.Camera.Current == 1 then
				ModEditor.Camera.Position[math.abs(id1)] = ModEditor.Camera.Position[math.abs(id1)] - ModEditor.Internal.Sign(id1)*ky*(100-ModEditor.Input.MouseY)
			end
		elseif ModEditor.Input.MouseY > get_option("height")-100 then
			ModEditor.Camera.Position[math.abs(id2)] = ModEditor.Camera.Position[math.abs(id2)] - ModEditor.Internal.Sign(id2)*kx*(100-(get_option("height")+1-ModEditor.Input.MouseY))
			if ModEditor.Camera.Current == 1 then
				ModEditor.Camera.Position[math.abs(id1)] = ModEditor.Camera.Position[math.abs(id1)] + ModEditor.Internal.Sign(id1)*ky*(100-(get_option("height")+1-ModEditor.Input.MouseY))
			end
		end
	end
	if ModEditor.Camera.Current ~= 0 then
		if ModEditor.Mode == 1 then
			local id
			local speed = 0.05
			local id1
			local id2
			local id3
			if ModEditor.Camera.Current == 1 then
				id1 = 1
				id2 = 2
				id3 = 3
			elseif ModEditor.Camera.Current == 2 then
				id1 = -2
				id2 = -3
				id3 = 1
			elseif ModEditor.Camera.Current == 3 then
				id1 = 1
				id2 = -3
				id3 = 2
			end
			if ModEditor.Input.Keys[113] then
				id = -id3
			elseif ModEditor.Input.Keys[101] then
				id = id3
			elseif ModEditor.Input.Keys[119] or ModEditor.Input.Keys[273] then
				id = -id2
			elseif ModEditor.Input.Keys[115] or ModEditor.Input.Keys[274] then
				id = id2
			elseif ModEditor.Input.Keys[100] or ModEditor.Input.Keys[275] then
				id = -id1
			elseif ModEditor.Input.Keys[97] or ModEditor.Input.Keys[76] then
				id = id1
			else
				id = 0
			end
			if id ~= 0 then
				for i = 1,#ModEditor.Windows.ObjectControl.ObjectList.Items do
					for d = 1,#ModEditor.ObjectList do
						if (ModEditor.Windows.ObjectControl.ObjectList.Items[i][1] == ModEditor.ObjectList[d].Name) and ModEditor.Windows.ObjectControl.ObjectList.Items[i][2] then
							ModEditor.ObjectList[d].Pos[math.abs(id)] = ModEditor.ObjectList[d].Pos[math.abs(id)] + ModEditor.Internal.Sign(id)*speed
						end
					end
				end
			end
		else
			local id
			if ModEditor.Input.Keys[113] then
				id = -3
			elseif ModEditor.Input.Keys[101] then
				id = 3
			elseif ModEditor.Input.Keys[119] or ModEditor.Input.Keys[273] then
				id = -1
			elseif ModEditor.Input.Keys[115] or ModEditor.Input.Keys[274] then
				id = 1
			elseif ModEditor.Input.Keys[100] or ModEditor.Input.Keys[275] then
				id = 2
			elseif ModEditor.Input.Keys[97] or ModEditor.Input.Keys[76] then
				id = -2
			else
				id = 0
			end
			if ModEditor.Camera.Current == 2 then
				if math.abs(id) == 1 then
					id = -ModEditor.Internal.Sign(id)*2
				elseif math.abs(id) == 2 then
					id = -ModEditor.Internal.Sign(id)*3
				elseif math.abs(id) == 3 then
					id = ModEditor.Internal.Sign(id)*1
				end
			elseif ModEditor.Camera.Current == 3 then
				if math.abs(id) == 2 then
					id = -ModEditor.Internal.Sign(id)*3
				elseif math.abs(id) == 3 then
					id = ModEditor.Internal.Sign(id)*2
				end
			end
			if id ~= 0 then
				for i = 1,#ModEditor.Windows.ObjectControl.ObjectList.Items do
					for d = 1,#ModEditor.ObjectList do
						if (ModEditor.Windows.ObjectControl.ObjectList.Items[i][1] == ModEditor.ObjectList[d].Name) and ModEditor.Windows.ObjectControl.ObjectList.Items[i][2] then
							ModEditor.ObjectList[d].Rot[math.abs(id)] = ModEditor.ObjectList[d].Rot[math.abs(id)] + ModEditor.Internal.Sign(id)
						end
					end
				end
			end
		end
	end
end
function ModEditor.Internal.On2D()
	ModEditor.Windows.Draw()
	set_color(0,0,0,1)
	if ModEditor.Mode == 1 then
		draw_text("Object Moving Mode. Use TAB key to change it.",0,get_option("height")-20)
	else
		draw_text("Object Rotating Mode. Use TAB key to change it.",0,get_option("height")-20)
	end
	ModEditor.Camera.Update()
	ModEditor.Input.Process()
end
function ModEditor.Internal.On3D()
	for i=1,#ModEditor.ObjectList do
		set_color(ModEditor.ObjectList[i].Color[2],ModEditor.ObjectList[i].Color[3],ModEditor.ObjectList[i].Color[4],ModEditor.ObjectList[i].Color[1])
		if ModEditor.ObjectList[i].Type == 1 then
			draw_box(ModEditor.ObjectList[i].Pos[1],ModEditor.ObjectList[i].Pos[2],ModEditor.ObjectList[i].Pos[3],ModEditor.ObjectList[i].Size[1],ModEditor.ObjectList[i].Size[2],ModEditor.ObjectList[i].Size[3],ModEditor.ObjectList[i].Rot[1],ModEditor.ObjectList[i].Rot[2],ModEditor.ObjectList[i].Rot[3])
		elseif ModEditor.ObjectList[i].Type == 2 then
			draw_sphere(ModEditor.ObjectList[i].Pos[1],ModEditor.ObjectList[i].Pos[2],ModEditor.ObjectList[i].Pos[3],ModEditor.ObjectList[i].Size[1])
		elseif ModEditor.ObjectList[i].Type == 3 then
			draw_capsule(ModEditor.ObjectList[i].Pos[1],ModEditor.ObjectList[i].Pos[2],ModEditor.ObjectList[i].Pos[3],ModEditor.ObjectList[i].Size[2],ModEditor.ObjectList[i].Size[1],ModEditor.ObjectList[i].Rot[1],ModEditor.ObjectList[i].Rot[2],ModEditor.ObjectList[i].Rot[3])
		end
	end
end
function ModEditor.Internal.OnMouseDown(button,x,y)
	if button == 1 then
		for i=1,#ModEditor.GUI.WindowList do
			if ModEditor.GUI.WindowList[i].Visible then
				if ModEditor.GUI.WindowList[i]:InWindow(x,y) then
					if ModEditor.GUI.ActiveWindowId ~= ModEditor.GUI.WindowList[i].Id then
						ModEditor.Windows.Activate(ModEditor.GUI.WindowList[i].Id)
					end
					ModEditor.Internal.MouseButtonPressed = true
					return ModEditor.GUI.WindowList[1]:MouseDown(x-ModEditor.GUI.WindowList[1].X,y-ModEditor.GUI.WindowList[1].Y,x,y)
				end
			end
		end
	elseif button == 4 then
		if ModEditor.Windows.Find(ModEditor.GUI.ActiveWindowId):InWindow(x,y) then
			return ModEditor.Windows.Find(ModEditor.GUI.ActiveWindowId):MouseScrollUp()
		else
			if ModEditor.Camera.Distance > 0.1 then
				ModEditor.Camera.Distance = ModEditor.Camera.Distance - 0.5
			end
		end
	elseif button == 5 then
		if ModEditor.Windows.Find(ModEditor.GUI.ActiveWindowId):InWindow(x,y) then
			return ModEditor.Windows.Find(ModEditor.GUI.ActiveWindowId):MouseScrollDown()
		elseif ModEditor.Camera.Current ~= 0 then
			ModEditor.Camera.Distance = ModEditor.Camera.Distance + 0.5
		end
	end
	return 0
end
function ModEditor.Internal.OnMouseUp(button,x,y)
	if button == 1 then
		ModEditor.Internal.MouseButtonPressed = false
		local wnd = ModEditor.Windows.Find(ModEditor.GUI.ActiveWindowId)
		if wnd ~= nil then
			return wnd:MouseUp(x-wnd.X,y-wnd.Y,x,y)
		end
	end
	return 0
end
function ModEditor.Internal.OnMouseMove(x,y)
	ModEditor.Input.MouseX = x
	ModEditor.Input.MouseY = y
	for i=1,#ModEditor.GUI.WindowList do
		ModEditor.GUI.WindowList[i]:MousePositionChange(x,y)
	end
	if ModEditor.Internal.MouseButtonPressed then
		local wnd = ModEditor.Windows.Find(ModEditor.GUI.ActiveWindowId)
		if wnd ~= nil then
			wnd:MouseMove(x-wnd.X,y-wnd.Y,x,y)
		end
	else
		for i=1,#ModEditor.GUI.WindowList do
			if ModEditor.GUI.WindowList[i]:InWindow(x,y) then
				return ModEditor.GUI.WindowList[i]:MouseMove(x-ModEditor.GUI.WindowList[i].X,y-ModEditor.GUI.WindowList[i].Y,x,y)
			end
		end
	end
end
function ModEditor.Internal.OnKeyDown(code)
	local result = 0
	if ModEditor.Input.KeyHook ~= nil then
		result = ModEditor.Input.KeyHook:OnKeyDown(code)
	end
	ModEditor.Input.Keys[code] = true
	if code == 305 then
		ModEditor.Input.RightCtrl = true
	elseif code == 306 then
		ModEditor.Input.LeftCtrl = true
	elseif code == 303 then
		ModEditor.Input.RightShift = true
	elseif code == 304 then
		ModEditor.Input.LeftShift = true
	end
	if ((code == 119) or (code == 115) or (code == 97) or (code == 100) or (code == 113) or (code == 101) or ((code >= 273) and (code <= 276))) and (ModEditor.Camera.Current ~= 0) or (code == 9) then
		result = 1
	end
	return result
end
function ModEditor.Internal.OnKeyUp(code)
	local result = 0
	if ModEditor.Input.KeyHook ~= nil then
		result = ModEditor.Input.KeyHook:OnKeyUp(code)
	end
	ModEditor.Input.Keys[code] = false
	if code == 305 then
		ModEditor.Input.RightCtrl = false
	elseif code == 306 then
		ModEditor.Input.LeftCtrl = false
	elseif code == 303 then
		ModEditor.Input.RightShift = false
	elseif code == 304 then
		ModEditor.Input.LeftShift = false
	elseif code == 9 then
		if ModEditor.Mode == 1 then
			ModEditor.Mode = 2
		else
			ModEditor.Mode = 1
		end
	end
	if ((code == 119) or (code == 115) or (code == 97) or (code == 100) or (code == 113) or (code == 101) or ((code >= 273) and (code <= 276))) and (ModEditor.Camera.Current ~= 0) or (code == 9) then
		result = 1
	end
	return result
end
function ModEditor.SaveMod(filename)
	local fname
	if (#filename > 4) and (string.sub(filename,#filename-3) ~= ".tbm") then
		fname = "mods/"..filename..".tbm"
	else
		fname = "mods/"..filename
	end
	local file = io.open(fname,"w+")
	file:write("# Mod was generated by SL7549's ModEditor\n")
	for i = 1,#ModEditor.ObjectList do
		local obj = ModEditor.ObjectList[i]
		file:write("\n")
		file:write("# Object: "..obj.Name.."\n")
		file:write("env_obj "..i.."\n")
		if obj.Type == 1 then
			file:write("shape box\n")
		elseif obj.Type == 2 then
			file:write("shape sphere\n")
		else
			file:write("shape capsule\n")
		end
		file:write("pos "..obj.Pos[1].." "..obj.Pos[2].." "..obj.Pos[3].."\n")
		file:write("color 0 0 0\n")
		file:write("rot "..obj.Rot[1].." "..obj.Rot[2].." "..obj.Rot[3].."\n")
		file:write("sides "..obj.Size[1].." "..obj.Size[2].." "..obj.SIze[3].."\n")
		file:close()
		file = nil
	end
end
function ModEditor.Internal.SetupHooks()
	ModEditor.EventManager.AddHook("Draw2D",ModEditor.Internal.On2D)
	ModEditor.EventManager.AddHook("Draw3D",ModEditor.Internal.On3D)
	ModEditor.EventManager.AddHook("MouseDown",ModEditor.Internal.OnMouseDown)
	ModEditor.EventManager.AddHook("MouseUp",ModEditor.Internal.OnMouseUp)
	ModEditor.EventManager.AddHook("MouseMove",ModEditor.Internal.OnMouseMove)
	ModEditor.EventManager.AddHook("KeyDown",ModEditor.Internal.OnKeyDown)
	ModEditor.EventManager.AddHook("KeyUp",ModEditor.Internal.OnKeyUp)
end
function ModEditor.Internal.Start()
	echo("ModEditor "..ModEditor.Version[1].."."..ModEditor.Version[2].."."..ModEditor.Version[3].." "..ModEditor.Version.ReleaseType.." by SL7549")
end
